package xyz.jangle.semaphore;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class PrintQueue {

	// 信号控制
	private final Semaphore semaphore;
	// 打印机组
	private final boolean prints[];
	// 同步控制
	private final ReentrantLock lock;

	public PrintQueue() {
		super();
		this.semaphore = new Semaphore(3);
		this.prints = new boolean[3];
		// 初始化打印机组
		for (int i = 0; i < prints.length; i++) {
			prints[i] = true;
		}
		this.lock = new ReentrantLock();

	}

	/**
	 * 获取可用的打印机编号
	 * 
	 * @return
	 */
	private int getPrints() {
		int ret = -1;
		try {
			lock.lock();
			for (int i = 0; i < prints.length; i++) {
				if (prints[i]) {
					ret = i;
					prints[i] = false;
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
		return ret;
	}

	/**
	 * 进行打印
	 */
	public void print() {
		try {
			semaphore.acquire();
			// semaphore只有3个，所以getPrints方法肯定能获取到打印机
			int i = getPrints();
			System.out.println(Thread.currentThread().getName() + ":模拟打印");
			TimeUnit.SECONDS.sleep((long) (Math.random() * 10));
			System.out.println(Thread.currentThread().getName() + ":打印完成");
			// 打印完成，释放打印机
			prints[i] = true;
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			semaphore.release();
		}

	}

	public static void main(String[] args) {
		PrintQueue printQueue = new PrintQueue();
		for (int i = 0; i < 20; i++) {
			new Thread(() -> {
				printQueue.print();
			}, "name" + i).start();
		}
	}

}
